package com.iRomantic.common.oss;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.aliyun.openservices.ClientConfiguration;
import com.aliyun.openservices.ClientException;
import com.aliyun.openservices.oss.OSSClient;
import com.aliyun.openservices.oss.OSSException;
import com.aliyun.openservices.oss.model.CannedAccessControlList;
import com.aliyun.openservices.oss.model.GetObjectRequest;
import com.aliyun.openservices.oss.model.OSSObject;
import com.aliyun.openservices.oss.model.OSSObjectSummary;
import com.aliyun.openservices.oss.model.ObjectListing;
import com.aliyun.openservices.oss.model.ObjectMetadata;

public class OSSService {
	
	private static final Logger logger = LoggerFactory.getLogger(OSSService.class);

	private static OSSService instance;
	
	//sso配置
	private static final String ACCESS_ID = "RM0aklzyZvkcHRSC";
	private static final String ACCESS_KEY = "P0djQHevvdG8z1vErOPSf13GMZc5oy";
	private static final String OSS_ENDPOINT = "http://oss.aliyuncs.com";
	
	private static final String BICKET_NAME = "test-iromantic";

	private static ClientConfiguration config;
	private static OSSClient client;

	private OSSService() {
		config = new ClientConfiguration();
		client = new OSSClient(OSS_ENDPOINT, ACCESS_ID, ACCESS_KEY, config);
	}

	public static OSSService getInstance() {
		if (instance == null) {
			synchronized (OSSService.class) {
				if (instance == null) {
					instance = new OSSService();
				}
			}
		}
		return instance;
	}

	/**
	 * 保存文件
	 * 
	 * @param path
	 * @throws Exception 
	 */
	public void save(String path, File file) throws Exception {
		// 可以使用ClientConfiguration对象设置代理服务器、最大重试次数等参数。
		ensureBucket(client, BICKET_NAME);
		setBucketPublicReadable(client, BICKET_NAME);
		try {
			logger.debug(path);
			uploadFile(client, BICKET_NAME, path, file);
		} catch (OSSException e) {
			e.printStackTrace();
			logger.error(e.getMessage());
			throw new Exception(e);
		} catch (ClientException e) {
			e.printStackTrace();
			logger.error(e.getMessage());
			throw new Exception(e);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			logger.error(e.getMessage());
			throw new Exception(e);
		}
	}
	
	/**
	 * 下载文件
	 * @param fileName
	 * @return
	 */
	public InputStream downloadFile(String fileName){
		OSSObject file = client.getObject(new GetObjectRequest(BICKET_NAME, fileName));
		return file.getObjectContent();
	}
	
	/**
	 *  删除文件
	 * @param path
	 */
	public void deleteObject(String path){
		logger.debug(path);
		client.deleteObject(BICKET_NAME, path);
	}

	/**
	 * 如果Bucket不存在，则创建它。
	 * @param client
	 * @param bucketName
	 * @throws OSSException
	 * @throws ClientException
	 */
	private static void ensureBucket(OSSClient client, String bucketName)
			throws OSSException, ClientException {
		if (client.doesBucketExist(bucketName)) {
			return;
		}
		// 创建bucket
		client.createBucket(bucketName);
	}

	/**
	 * 删除一个Bucket和其中的Objects
	 * @param client
	 * @param bucketName
	 * @throws OSSException
	 * @throws ClientException
	 */
	private static void deleteBucket(OSSClient client, String bucketName)
			throws OSSException, ClientException {
		ObjectListing ObjectListing = client.listObjects(bucketName);
		List<OSSObjectSummary> listDeletes = ObjectListing.getObjectSummaries();
		for (int i = 0; i < listDeletes.size(); i++) {
			String objectName = listDeletes.get(i).getKey();
			// 如果不为空，先删除bucket下的文件
			client.deleteObject(bucketName, objectName);
		}
		client.deleteBucket(bucketName);
	}

	/**
	 * 把Bucket设置为所有人可读
	 * @param client
	 * @param bucketName
	 * @throws OSSException
	 * @throws ClientException
	 */
	private static void setBucketPublicReadable(OSSClient client,
			String bucketName) throws OSSException, ClientException {
		// 创建bucket
		client.createBucket(bucketName);

		// 设置bucket的访问权限，public-read-write权限
		client.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
	}

	/**
	 * 上传文件
	 * @param client
	 * @param bucketName
	 * @param key
	 * @param filename
	 * @throws OSSException
	 * @throws ClientException
	 * @throws FileNotFoundException
	 */
	private static void uploadFile(OSSClient client, String bucketName,
			String key, String filename) throws OSSException, ClientException,
			FileNotFoundException {
		File file = new File(filename);

		ObjectMetadata objectMeta = new ObjectMetadata();
		objectMeta.setContentLength(file.length());
		// 可以在metadata中标记文件类型
		// objectMeta.setContentType("image/jpeg");

		InputStream input = new FileInputStream(file);
		client.putObject(bucketName, key, input, objectMeta);
	}
	
	/**
	 * 上传文件
	 * @param client
	 * @param bucketName
	 * @param key
	 * @param filename
	 * @param contentType
	 * @throws OSSException
	 * @throws ClientException
	 * @throws FileNotFoundException
	 */
	private static void uploadFile(OSSClient client, String bucketName,
			String key, String filename,String contentType) throws OSSException, ClientException,
			FileNotFoundException {
		File file = new File(filename);

		ObjectMetadata objectMeta = new ObjectMetadata();
		objectMeta.setContentLength(file.length());
		// 可以在metadata中标记文件类型
		objectMeta.setContentType(contentType);

		InputStream input = new FileInputStream(file);
		client.putObject(bucketName, key, input, objectMeta);
	}
	
	/**
	 * 上传文件
	 * @param client
	 * @param bucketName
	 * @param key
	 * @param file
	 * @throws OSSException
	 * @throws ClientException
	 * @throws FileNotFoundException
	 */
	private static void uploadFile(OSSClient client, String bucketName,
			String key, File file) throws OSSException, ClientException,
			FileNotFoundException {
		ObjectMetadata objectMeta = new ObjectMetadata();
		objectMeta.setContentLength(file.length());
		// 可以在metadata中标记文件类型
		// objectMeta.setContentType("image/jpeg");

		InputStream input = new FileInputStream(file);
		client.putObject(bucketName, key, input, objectMeta);
	}

	/**
	 * 下载文件
	 * @param client
	 * @param bucketName
	 * @param key
	 * @param filename
	 * @throws OSSException
	 * @throws ClientException
	 */
	private static void downloadFile(OSSClient client, String bucketName,
			String key, String filename) throws OSSException, ClientException {
		client.getObject(new GetObjectRequest(bucketName, key), new File(
				filename));
	}

}
